package org.lc.eic.messageconstruct.jaxb.content.string;

import javax.xml.bind.Binder;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.PropertyException;
import javax.xml.bind.Unmarshaller;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;


import org.lc.eic.messageconstruct.jaxb.content.ContentDecoder;
import org.lc.eic.messageconstruct.jaxb.content.ContentEncoder;
import org.lc.string_content._1_0.ObjectFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;




public class StringContentCoder implements ContentDecoder, ContentEncoder {
	
	private JAXBContext context = null;
	
	public String getEncodeContentType(){
		return String.class.getName();
	}
	
	public String getDecodeContentType(){
		return new ObjectFactory().createStringContent("").getName().getNamespaceURI();
	}

	public Object decodeContent(Element element) throws JAXBException {
		
		Unmarshaller unmarshaller = getUnmarshaller();
		
		JAXBElement<String> jxbElement = unmarshaller.unmarshal(element, String.class);
		
		return jxbElement.getValue();
		
	}
	
	public Element encodeContent(Object obj) throws Exception {
		Marshaller marshaller = getMarshaller();		

		
		try {
            marshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper",new NamespacePrefixMapperImpl());
        } catch( PropertyException e ) {
            // if the JAXB provider doesn't recognize the prefix mapper,
            // it will throw this exception. Since being unable to specify
            // a human friendly prefix is not really a fatal problem,
            // you can just continue marshalling without failing
            ;
        }

		
		DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();		
		DocumentBuilder documentBuilder = builderFactory.newDocumentBuilder();	
		Document doc = documentBuilder.newDocument();		
		
		marshaller.marshal( new ObjectFactory().createStringContent((String) obj), doc);

		
		return doc.getDocumentElement();
	}
	
	
	private Marshaller getMarshaller() throws JAXBException{
		JAXBContext ctx = getContext();		
		return ctx.createMarshaller();	

	}
	private Unmarshaller getUnmarshaller() throws JAXBException{
		JAXBContext ctx = getContext();		
		return ctx.createUnmarshaller();
	}
	private JAXBContext getContext() throws JAXBException {
		if(this.context == null){
			synchronized(this){
				if(this.context == null){
					context = JAXBContext.newInstance(ObjectFactory.class.getPackage().getName(), ObjectFactory.class.getClassLoader());
				}
			}
			
		}
		return this.context;
	}


}
